;(function(){
  'use strict';
  angular.module('services.omdisplay.sysBusStat')
    .factory('TradePercentageServer',tradePercentageServer)
    .factory('TradeRatioSelector',tradeRatioSelector)
    .factory('TradeRatioQueryObj',tradeRatioQueryObj)
    .factory('TradeRatioViewObj',tradeRatioViewObj);
  /**
   * 交易总量占比查询server
   * @param   Restangular    异步查询方法库
   * @return                 server实例
   */
  function tradePercentageServer(Restangular){
    //返回包含查询方法的实例作为server被创建
    return {
      province: provinceQuery,
      unProvince: unProvinceQuery
    };
    /**
     * 分省份交易总量占比查询
     * @param   params     查询参数
     * @param   callback   查询响应后的回调函数
     * @return             一个promise实例
     */
    function provinceQuery(params,callback) {
      return Restangular.all('sas/OMdisplay/UpayBusinessStatistics/provincePercentage').post(params).then(callback);
    }
    /**
     * 不分省份交易总量占比查询
     * @param   params     查询参数
     * @param   callback   查询响应后的回调函数
     * @return             一个promise实例
     */
    function unProvinceQuery(params,callback) {
      return Restangular.all('sas/OMdisplay/UpayBusinessStatistics/noProvincePercentage').post(params).then(callback);
    }
  }

  tradePercentageServer.$inject = ['Restangular'];
  /**
   * 交易总量占比查询选项service
   * @param   COREDATA    提供公用数据
   * @return              选项service实例
   */
  function tradeRatioSelector(COREDATA){
    //时间格式数组,位置对应账期代码
    var formatArr = [undefined,'yyyy-MM-dd',undefined,'yyyy-MM-01','yyyy-01-01','yyyy-01-01'];
    //初始化查询选项
    var selector = {
      //业务线下拉选项
      businessLine:COREDATA.BUSINESSLINE,
      //单位下拉选项,目前仅选择'个'作为单位
      unit:[ {name : '个', code : '0'}, {name : '万', code : '1'}, {name : '亿', code : '2'} ],
      //省份下拉选项
      provinceCodes:COREDATA.PROVINCES,
      //账期下拉选项
      timeType:COREDATA.TIMETYPES
    };
    //返回实例作为service被创建
    return {
      selector : selector,
      formatArr : formatArr
    };
  }

  tradeRatioSelector.$inject = ['COREDATA'];
  /**
   * 交易总量占比查询service
   * @param   COREDATA              提供公共数据
   * @param   CoreService           提供公共方法
   * @param   TradePercentageServer 交易总量占比查询服务
   * @param   TradeRatioSelector    提供查询选项实例
   * @param   TradeRatioViewObj     交易总量占比页面展示控制实例
   * @return                        返回查询service实例
   */
  function tradeRatioQueryObj(COREDATA,CoreService,CoreLoading,TradePercentageServer,TradeRatioSelector,TradeRatioViewObj){
    //查询参数集
    var param;
    //查询日期参数
    var date;
    //页面控制开关
    var flag;
    //返回实例
    return {
      initDate : initDate,
      initParam : initParam,
      initFlag : initFlag,
      queryFn : queryFn,
      changeProvincialFn : changeProvincialFn
    };
    //初始化查询参数并返回
    function initParam(){
      param = {
        quarter:{}
      };
      return param;
    }
    //初始化页面控制开关
    function initFlag(){
      flag = {
        formIsFold:false, //查询表单是否收拢
        provincial:true,  //是否分省
        isQuery:false,    //是否已经查询出结果
        showTable:true,   //是否显示列表
        exportUrl:COREDATA.FORMPREFIX+'OMdisplay/UpayBusinessStatistics/provincialExport'
      };
      return flag;
    }
    //初始化查询日期参数
    function initDate(){
      date = {}; //将日期对象清空
      var now = new Date(); //当前client系统时间
      var year = now.getFullYear(); //年
      var month = now.getMonth();  //月
      var day = now.getDate()-1;  //日
      var timeType = '1';  //默认账期代码为 日:1
      //如果页面选择过账期,则修改timeType的值
      if(param.timeType){
        timeType = param.timeType.timeTypeCode;
      }
      //根据账期判断初始化相应日期参数的值
      switch(timeType){
        case '3':
          date.startTime = new Date(year,month);
          date.endTime = new Date(year,month);
          break;
        case '5':
          date.startTime = year;
          date.endTime = year;
          break;
        default:
          date.startTime = new Date(year,month,day);
          date.endTime = new Date(year,month,day);
      }
      //返回日期参数
      return date;
    }
    //改变是否分省标志以及导出路径
    function changeProvincialFn(){
      if(flag.provincial){
        flag.exportUrl = COREDATA.FORMPREFIX+'OMdisplay/UpayBusinessStatistics/provincialExport';
      }else{
        flag.exportUrl = COREDATA.FORMPREFIX+'OMdisplay/UpayBusinessStatistics/unprovincialExport';
      }
      //清空查询参数中的省份数组
      param.provinceCodes = [];
    }
    //查询方法
    function queryFn(){
      // 声明查询参数
      var tempParam;
      //form表单验证存在无效则不进行查询
      if(!flag.formIsFold) {
        tempParam = setParam();
        //发送查询请求
        if(flag.provincial){
          //载入动画
          CoreLoading.setState(true);
          TradePercentageServer.province(tempParam,function(res){
            if(res.state === '10000' && res.data.length > 0){
              //页面控制对象设置页面显示数据
              TradeRatioViewObj.setViewObj(res.data,flag.provincial,tempParam,param);
              //关闭载入动画
              CoreLoading.setState(false);
              //切换表单收拢状态
              flag.formIsFold = !flag.formIsFold;
              flag.isQuery = true;
            }else{
              flag.isQuery = false;
              flag.showTable = '';
              //关闭载入动画
              CoreLoading.setState(false);
              //弹出提示框
              CoreService.dialog(res.state);
            }
          });
        }else{
          //载入动画
          CoreLoading.setState(true);
          TradePercentageServer.unProvince(tempParam,function(res){
            if(res.state === '10000' && res.data.length > 0){
              //页面控制对象设置页面显示数据
              TradeRatioViewObj.setViewObj(res.data,flag.provincial,tempParam,param);
              //关闭载入动画
              CoreLoading.setState(false);
              //切换表单收拢状态
              flag.formIsFold = !flag.formIsFold;
              flag.isQuery = true;
            }else{
              flag.isQuery = false;
              flag.showTable = '';
              //关闭载入动画
              CoreLoading.setState(false);
              //弹出提示框
              CoreService.dialog(res.state);
            }
          });
        }
      }else{
        //切换表单收拢状态
        flag.formIsFold = !flag.formIsFold;
      }
    }
    //根据model生成相应param
    function setParam(){
      //日期格式
      var format;
      //临时查询参数
      var tempParam = {};
      //选项集
      var selector = TradeRatioSelector.selector;
      //业务线选项处理
      if(param.businessLine){
        tempParam.businessLine = [param.businessLine.businessLineCode];
      }else{
        tempParam.businessLine = [];
      }

      //单位选项处理  目前仅使用'个'作为查询单位
      // if(param.unit){
      //   tempParam.unit = param.unit.code;
      // }else{
      //   tempParam.unit = selector.unit[0].code;
      // }
      tempParam.unit = selector.unit[0].code;

      //账期选项处理
      if(param.timeType){
        tempParam.timeType = param.timeType.timeTypeCode;
      }else{
        tempParam.timeType = selector.timeType[0].timeTypeCode;
      }

      format = TradeRatioSelector.formatArr[tempParam.timeType];  //根据账期获得日期格式化数组中对应格式

      //省公司选项处理
      if(flag.provincial && param.provinceCodes){
        tempParam.provinceCodes = param.provinceCodes.map(function(item){return item.provinceCode;});
        // tempParam.provinceNames = param.provinceCodes.map(function(item){return item.provinceName;});
      }else{
        tempParam.provinceCodes = [];
        // tempParam.provinceNames = [];
      }

      //根据所选账期对日期条件处理
      if(param.timeType){
        switch(param.timeType.timeTypeCode){
          case '4':
            tempParam.startTime = param.quarter.startTime.substr(0,4)+'-01-01';
            tempParam.endTime = param.quarter.endTime.substr(0,4)+'-01-01';
            tempParam.startQuarter = param.quarter.startTime.substr(4,1);
            tempParam.endQuarter = param.quarter.endTime.substr(4,1);
            break;
          case '5':
            tempParam.startTime = date.startTime+'-01-01';
            tempParam.endTime = date.endTime+'-01-01';
            break;
          default :
            tempParam.startTime = CoreService.dateFormat(date.startTime,format);
            tempParam.endTime = CoreService.dateFormat(date.endTime,format);
        }
      }else{
        tempParam.startTime = CoreService.dateFormat(date.startTime,format);
        tempParam.endTime = CoreService.dateFormat(date.endTime,format);
      }
      //返回参数
      return tempParam;
    }
  }

  tradeRatioQueryObj.$inject = ['COREDATA','CoreService','CoreLoading','TradePercentageServer','TradeRatioSelector','TradeRatioViewObj'];
  /**
   * 交易总量占比页面展示service
   * @param   TradeRatioSelector 交易总量占比查询选项service
   * @param   $filter            angular过滤器,包含了自定义过滤器
   * @param   $timeout           angular内置定时器
   * @param   CoreService        公共服务
   * @return                     返回了包含可供外部调用方法的实例
   */
  function tradeRatioViewObj(TradeRatioSelector,$filter,$timeout,CoreService,PublicFn){
    //页面数据实例
    var viewObj;
    //echarts实例集
    var chartObj;
    return {
      initViewObj : initViewObj,
      initChartObj : initChartObj,
      destroyChartObj : destroyChartObj,
      setViewObj : setViewObj
    };
    //初始化页面展示数据对象
    function initViewObj(){
      viewObj = {
        //汇总
        total : {name:'汇总',businessAmount:0,orderMoney:0,rechargeMoney:0},
        //标题
        title:'',
        //数列
        series:[],
        //导出参数
        exportParam:{},
        //是否分省标志
        provincial:true,
        //是否已查询成功标志
        isPrepare:false
      };
      return viewObj;
    }
    //初始化并返回echarts实例集,并解绑鼠标hover效果
    function initChartObj(){
      chartObj = {};
      //业务量
      chartObj.businessAmountChart = echarts.init(document.getElementById('businessAmount'));
      chartObj.businessAmountChart.un(echarts.config.EVENT.HOVER);
      //充值金额
      chartObj.orderMoneyChart = echarts.init(document.getElementById('orderMoney'));
      chartObj.orderMoneyChart.un(echarts.config.EVENT.HOVER);
      //订单金额
      chartObj.rechargeMoneyChart = echarts.init(document.getElementById('rechargeMoney'));
      chartObj.rechargeMoneyChart.un(echarts.config.EVENT.HOVER);
      return chartObj;
    }
    //销毁并返回空对象
    function destroyChartObj(){
      chartObj = {};
      return chartObj;
    }
    /**
     * 生成图表及列表标题
     * @param   param        查询参数
     * @param   businessName 业务统计维度名称
     * @param   nameStr      业务线名称
     * @return               标题
     */
    function getTitle(param,businessName,nameStr,diffProName,timeTitle){
      //标题
      var title;
      //开始时间与结束时间是否一致
      var timeIsNotSame;
      //季度名称数组,位置对应季度code
      var quarterArr = [undefined,'第一季度','第二季度','第三季度','第四季度'];
      //根据账期判断开始时间与结束时间是否一致
      if(param.timeType === '4'){
        timeIsNotSame = (param.startTime !== param.endTime)||(param.startQuarter !== param.endQuarter);
      }else{
        timeIsNotSame = param.startTime !== param.endTime;
      }
      //生成账期区间
      switch(param.timeType){
        case '5' :
          viewObj.duration = timeIsNotSame?(param.startTime.substr(0,4)+'_'+param.endTime.substr(0,4)):(param.startTime.substr(0,4));
          break;
        case '4' :
          viewObj.duration = timeIsNotSame?(param.startTime.substr(0,4)+quarterArr[param.startQuarter]+'_'+param.endTime.substr(0,4)+quarterArr[param.endQuarter]):(param.startTime.substr(0,4)+quarterArr[param.startQuarter]);
          break;
        case '3' :
          viewObj.duration = timeIsNotSame?(param.startTime.substr(0,7).replace(/-/g,'')+'_'+param.endTime.substr(0,7).replace(/-/g,'')):(param.startTime.substr(0,7).replace(/-/g,''));
          break;
        case '1' :
          viewObj.duration = timeIsNotSame?(param.startTime.replace(/-/g,'')+'_'+param.endTime.replace(/-/g,'')):(param.startTime.replace(/-/g,''));
          break;
      }
      //生成标题
      return timeTitle+' '+nameStr+' '+businessName+diffProName+'占比';
    }
    /**
     * 设置页面数据展示对象
     * @param  data       响应数据集
     * @param  provincial 是否分省标志
     * @param  param      查询参数集
     * @param  model      参数model
     */
    function setViewObj(data,provincial,param,model){
      //统计数据总量 如业务总量 交易金额总量
      var sum;
      //已选中业务线名称
      var nameStr;
      //已选中的选项
      var selectedItems;
      //属性名称
      var propertyName;
      //列表用数据对象集
      var tempItems = {};
      //图表用数据对象集
      var items = {businessAmount:{},orderMoney:{},rechargeMoney:{}};
      //echarts实例option集
      var options = {};
      //下拉选项集
      var selector = TradeRatioSelector.selector;
      //业务统计维度名称数组
      var businessArr = ['业务量','订单金额','充值金额'];
      //清空数列
      viewObj.series = [];
      //重置统计
      viewObj.total = {name:'汇总',businessAmount:0,orderMoney:0,rechargeMoney:0};
      //设置是否分省标志
      viewObj.provincial = Boolean(provincial);
      //属性名
      propertyName = viewObj.provincial ? 'provinceName' :'businessLineName';
      //若已选择业务线则找出所选业务线
      if(param.businessLine && param.businessLine.length !== 0) {
        angular.forEach(selector.businessLine,function(item){
          if(item.businessLineCode === param.businessLine[0]){
            selectedItems = item;
            //获取所选业务线名称
            nameStr = selectedItems.businessLineName;
          }
        });
      }else{
        //若未选择业务线,则获取全部业务线作为选中选项,并获取全部业务线的名称
        selectedItems = selector.businessLine;
        nameStr = '统一支付系统';
      }
      //若分省份查询,则显示维度按省份分组
      if(viewObj.provincial){
        //若省份选项选择了省份,且不止一个,则将已选省份数组排序后赋值
        if(model.provinceCodes && model.provinceCodes.length >= 1) {
          selectedItems = CoreService.sort(model.provinceCodes,'provinceCode');
        }else{
          //若未选择省份,则获取全部省份
          selectedItems = selector.provinceCodes;
        }
      }
      //如果用来展示的维度中已选中项有多个,遍历selectedItems
      if(is.array(selectedItems)){
        //item[propertyName]:这里propertyName 为 provinceName 及 businessLineName 其中一种值
        angular.forEach(selectedItems,function(item){
          //遍历中每次迭代都初始化对应数据的对象
          tempItems[item[propertyName]] = {
            businessAmount:0,
            orderMoney:0,
            rechargeMoney:0,
            percentage:{businessAmount:0,orderMoney:0,rechargeMoney:0}
          };
          //赋予该对象在分组维度中对应选项的名称
          tempItems[item[propertyName]][propertyName] = item[propertyName];
          //如果分省份,则增加一个省份代码属性
          if(viewObj.provincial){
            tempItems[item[propertyName]].provinceCode = item.provinceCode;
          }
          //赋予分组维度中对应选项名称以及数值初始化用作图表计算
          items.businessAmount[item[propertyName]] = {value:0};
          items.businessAmount[item[propertyName]][propertyName] = item[propertyName];
          items.orderMoney[item[propertyName]] = {value:0};
          items.orderMoney[item[propertyName]][propertyName] = item[propertyName];
          items.rechargeMoney[item[propertyName]] = {value:0};
          items.rechargeMoney[item[propertyName]][propertyName] = item[propertyName];
        });
      }else{
        //初始化数据对象
        tempItems[selectedItems[propertyName]] = {
          businessAmount:0,
          orderMoney:0,
          rechargeMoney:0,
          percentage:{businessAmount:0,orderMoney:0,rechargeMoney:0}
        };
        //赋予所选择对应选项的名称
        tempItems[selectedItems[propertyName]][propertyName] = selectedItems[propertyName];
        //数值初始化用作图表计算
        items.businessAmount[selectedItems[propertyName]] = {value:0};
        items.businessAmount[selectedItems[propertyName]][propertyName] = selectedItems[propertyName];
        items.orderMoney[selectedItems[propertyName]] = {value:0};
        items.orderMoney[selectedItems[propertyName]][propertyName] = selectedItems[propertyName];
        items.rechargeMoney[selectedItems[propertyName]] = {value:0};
        items.rechargeMoney[selectedItems[propertyName]][propertyName] = selectedItems[propertyName];
      }
      //遍历响应数据,并根据分组维度唯一code赋值给对应项
      angular.forEach(data,function(item){
        items.businessAmount[item[propertyName]].value = Number(item.businessAmount);
        tempItems[item[propertyName]].businessAmount = Number(item.businessAmount);
        items.orderMoney[item[propertyName]].value = Number(item.orderMoney);
        tempItems[item[propertyName]].orderMoney = Number(item.orderMoney);
        items.rechargeMoney[item[propertyName]].value = Number(item.rechargeMoney);
        tempItems[item[propertyName]].rechargeMoney = Number(item.rechargeMoney);
        //累加统计值
        viewObj.total.businessAmount += Number(item.businessAmount);
        viewObj.total.orderMoney += Number(item.orderMoney);
        viewObj.total.rechargeMoney += Number(item.rechargeMoney);
      });
      var timeTitle = PublicFn.fmtDateTitle(param,'timeType');
      var diffProName = viewObj.provincial ? '各省' : '';
      //生成echarts实例option
      options.businessAmount = new ChartOpt(getTitle(param,businessArr[0],nameStr,diffProName,timeTitle),businessArr[0]);
      options.orderMoney = new ChartOpt(getTitle(param,businessArr[1],nameStr,diffProName,timeTitle),businessArr[1]);
      options.rechargeMoney = new ChartOpt(getTitle(param,businessArr[2],nameStr,diffProName,timeTitle),businessArr[2],viewObj);
      // viewObj.duration = timeTitle;
      //设置页面显示标题
      viewObj.title = timeTitle+' '+nameStr+diffProName+'占比明细';
      //遍历之前生成数列 共三次循环 分别对应 业务量 充值金额 订单金额
      angular.forEach(items,function(subItems,key){
        //调用自定义排序方法返回新数组
        var arr = bubbleSort(subItems);
        //初始化合计值
        sum = 0;
        //累加汇总
        for(var i = 0; i < arr.length; i++){
          sum = sum + Number(arr[i].value);
        }
        //遍历排序后的数组
        angular.forEach(arr,function(subItem,index){
          //获取占比
          var value =(subItem.value/(sum?sum:1)*100);
          //生成对象用于push进option中的series的data数组里
          var tempObj = {
            name: subItem[propertyName]+'\n'+value.toFixed(4)+'%', //单项数据展示名称
            value: value,  //占比
            itemStyle:{  //显示样式设置
              normal:{
                label:{
                  show:false
                },
                labelLine:{
                  show:false
                }
              }
            }
          };
          //如果该项为前八项则显示标签名以及标签线
          if(index < 8){
            tempObj.itemStyle.normal.label.show = true;
            tempObj.itemStyle.normal.labelLine.show = true;
          }
          //percentage[key]对应每一个展示维度的百分率
          tempItems[subItem[propertyName]].percentage[key] = value;
          //push进data数组中
          options[key].series[0].data.push(tempObj);
        });
        //设置显示字体大小
        options[key].series[0].itemStyle.normal = {label: {textStyle:{ fontSize: 12}}};
      });
      //向页面图标数列push每个所选项对象
      for(var o in tempItems){
         viewObj.series.push(tempItems[o]);
      }
      //设置echarts option
      setOption(options,param);
      //默认显示业务量图表
      viewObj.queryType = 1;
      return viewObj;
    }
    /**
     * 自定义排序方法
     * @param   items 需要按value值排序的数组
     */
    function bubbleSort(items){
      var arr=[];
      //将传入的数组每一项重新推入新数组中
      for(var o in items){
        arr.push(items[o]);
      }
      //排序数组 这里传入一个自定义function 根据返回值 true or false 选择是否交换两个元素位置
      arr.sort(function(x,y){
        return Number(y.value)-Number(x.value);
      });
      //返回排序后的数组
      return arr;
    }
    /**
     * 设置echarts option
     * @param  options echarts用option
     * @param  param   查询参数,用来设置导出参数
     */
    function setOption(options,param){
      chartObj.businessAmountChart.clear();
      chartObj.businessAmountChart.setOption(options.businessAmount);
      chartObj.orderMoneyChart.clear();
      chartObj.orderMoneyChart.setOption(options.orderMoney);
      chartObj.rechargeMoneyChart.clear();
      chartObj.rechargeMoneyChart.setOption(options.rechargeMoney);
      //echarts实例获取base64需要等待图片生成完成,故延时一秒执行
      $timeout(function(){setExportParam(param);},1000);
    }
    /**
     * 设置导出参数
     * @param  param 查询参数,用来设置导出参数
     */
    function setExportParam(param){
      var  tempParam = {};
      //拷贝查询参数到新的临时对象中
      angular.copy(param,tempParam);
      //设置所选账期间隔时长
      tempParam.duration = viewObj.duration;
      //设置图标标题
      tempParam.title = viewObj.title;
      //导出图片base64数组
      tempParam.base64s = [];
      tempParam.base64s.push(chartObj.businessAmountChart.getDataURL().split(',')[1]);
      tempParam.base64s.push(chartObj.orderMoneyChart.getDataURL().split(',')[1]);
      tempParam.base64s.push(chartObj.rechargeMoneyChart.getDataURL().split(',')[1]);
      //序列化参数
      viewObj.exportParam = JSON.stringify(tempParam);
      //是否可以导出标志
      viewObj.isPrepare = true;
    }
    //echarts 图标option 构造函数
    function ChartOpt(title,subTitle){
      this.title = { text: title, x: 'center',y:40,textStyle:{fontSize:16}};
      this.animation = false;
      this.tooltip = { show: true,formatter:function(params){
        var res = params.name.replace(/\n/g,'<br/>');
        return res;
      }};
      this.series = [
        {
          name:subTitle,
          type:'pie',
          center: ['50%','50%'],
          radius : ['0%','45%'],
          data:[],
          clickable:false,
          itemStyle:{
            emphasis: {
              color: 'rgba(0,0,0,0)'
            }
          }
        }
      ];
    }
  }

  tradeRatioViewObj.$inject = ['TradeRatioSelector','$filter','$timeout','CoreService','PublicFn'];

})();